/* 
 JS中的盒子模型属性：基于JS内置的API，来获取元素的样式
   如何基于JS“修改”元素的样式
     + 设置行内样式
       box.style.xxx = xxx
       box.style.cssText = '...'
     + 设置样式类名
       box.className = '...'
       box.classList.add/remove/toggle('...')

   如何基于JS“获取”元素样式
     + 获取行内样式「要求：样式必须写在行内上」
       box.style.xxx  
     + 获取元素“所有”经过浏览器“计算过”的样式
       window.getComputedStyle([element],[伪元素]) 
       + 只要元素在浏览器中渲染了，则其样式都可以获取，不论写在哪，也不论是否写！
       + 获取的是一个CSSStyleDeclaration类的实例对象
       + 所有样式以键值对的形式存储在实例对象中
       + [伪元素]可以不设置 
     + 可以基于JS中的盒子模型属性，来获取元素的样式
       + clientWidth/clientHeight/clientTop/clientLeft
       + offsetWidth/offsetHeight/offsetTop/offsetLeft/offsetParent
       + scrollWidth/scrollHeight/scrollTop/scrollLeft
     + 获取元素距离可视窗口的位置信息「left/right/bottom/top...」
       box.getBoundingClientRect()
       + 获取盒子顶部/底部/左侧/右侧，距离可视窗口“左上角(上边和左边)”的位置
       + 获取的值可能是负数


===================
clientWidth/Height:可视区域的宽高{内容宽高+padding}，内容是否有溢出对其无影响
   扩展：获取可视窗口(或浏览器/或一屏幕)的宽高
   document.documentElement.clientWidth
   document.documentElement.clientHeight

clientLeft/Top:获取左(上)边框的宽度

offsetWidth/Height:在clientWidth/Height的基础上加边框，内容是否有溢出对其无影响

scrollWidth/Height:获取真实内容的宽高(含溢出的内容)
   如果没有内容溢出，则获取的值和clientWidth/Height一样
   如果有内容溢出，则是真实内容(含溢出的)+上(或左)padding
   特殊：获取的值仅供参考，因为受到不同浏览器以及是否设置overflow的影响，获取的值是不太统一的！！
   扩展：获取真实页面的宽高
   document.documentElement.scrollWidth
   document.documentElement.scrollHeight

scrollLeft/Top:获取滚动条卷去的宽度(或高度)
   在所有的盒子模型属性中，只有这两个是“可读写”的，其余都是“只读”的！
   边界值：
     + 最小边界 0
     + 最大边界 页面真实的高度 - 可视窗口的高度
 */

(function () {
    const back = document.querySelector('.back'),
        html = document.documentElement;

    /* 
     * 伴随页面的滚动，监测back的显示隐藏「卷去的高度超过一屏幕则显示」
     *   + window.onscroll 只要滚动条发生滚动，就会触发此事件
     */
    const watchScroll = function watchScroll() {
        if (html.scrollTop >= html.clientHeight) {
            back.style.display = 'block';
            return;
        }
        back.style.display = 'none';
    };
    window.onscroll = watchScroll;

    /* 
     * 点击回到顶部
     *  + 立即回
     *  + 动画:固定步长
     *  + 动画:固定时间
     */

    // 固定时间的匀速运动公式：执行公式返回元素最新的位置
    // t:time已经运动的时间  b:begin起始位置  c:change总距离  d:duration总时间
    const linear = function linear(t, b, c, d) {
        return t / d * c + b;
    };
    back.onclick = function () {
        back.style.display = 'none';
        window.onscroll = null;
        let time = 0,
            begin = html.scrollTop,
            change = 0 - begin,
            duration = 1000;
        let timer = setInterval(() => {
            time += 16;
            if (time >= duration) {
                // 结束动画
                html.scrollTop = 0;
                clearInterval(timer);
                window.onscroll = watchScroll;
                return;
            }
            html.scrollTop = linear(time, begin, change, duration);
        }, 16);
    };

    /* back.onclick = function () {
        back.style.display = 'none';
        window.onscroll = null;
        let step = 100;
        let timer = setInterval(() => {
            html.scrollTop -= step;
            if (html.scrollTop <= 0) {
                // 动画结束
                clearInterval(timer);
                html.scrollTop = 0;
                window.onscroll = watchScroll;
            }
        }, 16);
    }; */

    /* back.onclick = function () {
        // 立即回到顶部
        html.scrollTop = 0;
    }; */
})();